home *** CD-ROM | disk | FTP | other *** search
-
- /* CON_FILT.EXE example file for TstHost.
- compile with BCC CON_FILT.C
- -------------------------------------------------------------------------------
- NOTE: if you decide to modify this code, please read the CFILT_??.DOC file
- to ensure compatibility with the others md2 filtering and password decoding
- sistem.
- -------------------------------------------------------------------------------
- This server use the CON_FILT.PSW file, that have this format:
- Every empty line, or line that start with the '#' are ignored.
- The first valid line are password request prompt.
- The second line is the filter mode, 0 for OPEN SYTEM, 1 for CLOSED SYSTEM.
- The others line are the callsign, without ssid, flag and its password, like:
- CALL FLAG PASSWORD
- CALL FLAG PASSWORD
- ... etc.
-
- NOTE: PASSWORD is not needed if FLAG=0
-
-
- OPEN SYSTEM MODE
- If the call is not declared in the con_filt.psw file, the user will be
- connected without password request, userful for bbs forward, or user that
- do not want password.
- If a callsign is declared:
- if FLAG=0, the callsign is excluded, disconneted.
- if FLAG=1, the callsign is connected after the password request.
-
- CLOSE SYSTEM MODE
- Only the callsign declared in the con_filt.psw may access to the system,
- the other will be disconneted.
- For declared callsign:
- if FLAG=0, the connection is accepted without password request.
- if FLAG=1, the connection is accepted, but the password will be requested.
-
- > Prompt must be long at most 80 characters
- > Password my be long at most 255 characters, without space.
- > This program, if renamed C_FILTER.EXE, run also under FBB 5.15a and upper
-
- The server use a temporary file XXXXXX.CFT, where XXXXXX is the callsign of
- the user, to store the calculated password and date time of any unsuccesful
- logon; you do not need to touch this file, all management will be done by
- con_filt; the temporary file will be automatically deleted when not more
- needed.
-
- The server use both the standard 5 letters password and the MD2 (c)RSA
- alghoritm. The user may answer in standard or md2 mode, the server will
- decode automatically the corrected mode.
-
- The line arguments given to the CON_FILT from TstHost are :
- - Callsign (format as IK1GKJ).
- - Level number (0 is the first time, up to 255).
- - reserved, always 0
- - reserved, always 0
- - reserved, always 0
- - reserved, always 1
- - Received data (each word is a new argument).
-
- The CON_FILT program end with an exit value. This value tells the PMS what do:
- - 0 accept connection.
- - 1 the program will be called again and the level number is incremented.
- - 2 the user will be disconnected.
-
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <io.h>
- #include <time.h>
- #include <string.h>
- #include "md2code.c"
-
- void error(void); /* this function exit with a value of 2 */
-
- char call[7]="",
- call1[7]="",
- buffer[400]="",
- tmp[100]="",
- UserFile[20]="",
- BbsPrompt[81]="",
- Password[256]="",
- ExcludeMessage[]="\n*** Sorry, you can not access to this system.\n";
- int pass[5],
- Port,
- level,
- SystemMode,
- UserFlag;
- long timet;
- FILE *pf;
- unsigned char MD2digest[16];
- MD2_CTX context;
-
- main(int ac, char **av)
- {
-
- /* FIRST GET LEVEL NUMBER AND THE CALLSIGN, MAKE USER FILE NAME */
- int i=0,found=0,jj;
- if(ac<7) error();
- level=atoi(av[2]);
-
- Port=atoi(av[6]); /* THIS AND NEXT INSTRUCTION ARE ONLY FOR FBB */
- if(!Port) return 0; /* PORT 0 IS CONSOLLE UNDER FBB */
-
- if(sscanf(av[1],"%6[a-zA-Z0-9]",call)!=1) error();
- sprintf(UserFile,"%s.CFT",call);
-
- /* AT CONNECTION, READ IN CON_FILT.PSW, TO SEARCH FOR THE USER CALLSIGN
- THE FIRST VALID LINE IN THE FILE ARE THE PMS REQUEST PASSWORD PROMPT
- NEXT THE SISTEM OPEN/CLOSE MODE
- NEXT THE USER CALL FLAG PASSWORD */
- if(!level)
- {
- if((pf=fopen("CON_FILT.PSW","rt"))==NULL) error();
- i=0;
- while(fgets(buffer,399,pf))
- {
- if(*buffer==0 || *buffer=='\n' || *buffer=='#') continue;
- if(!i) {
- if(sscanf(buffer," %80[^\n]",BbsPrompt)!=1) error();
- i++;
- continue;
- }
- if(i==1){
- if(sscanf(buffer," %d",&SystemMode)!=1) error();
- i++;
- continue;
- }
- jj=sscanf(buffer," %6[a-zA-Z0-9] %d %255s",call1,&UserFlag,Password);
- if(jj<2 || (jj<3 && UserFlag)) error();
- if(stricmp(call,call1)) continue;
- found=1;
- break;
- }
- if(ferror(pf)) error();
- fclose(pf);
- if(!SystemMode) /* IN OPEN SYSTEM MODE */
- { /* CALL NOT FOUND, ACCEPT CONNECTION */
- if(!found) exit(0); /* WITHOUT PASSWORD */
- if(!UserFlag) /* IF FLAG=0, CALLSIGN IS EXCLUDED */
- {
- puts(ExcludeMessage);
- exit(2); /* OTHERWISE ASK FOR THE PASSWORD */
- }
- }
- else { /* IN CLOSED SYSTEM MODE */
- if(!found) /* CALL NOT FOUND, DISCONNECT */
- {
- puts(ExcludeMessage);
- exit(2);
- }
- if(!UserFlag) exit(0); /* FLAG=0, CONNECT WITHOUT PASSWORD */
- } /* OTHERWISE ASK FOT THE PASSWORD */
-
- /* NEXT CALCULATE 5 RANDOM NUMERS FOR STANDARD PASSWORD */
- level=strlen(Password);
- randomize();
- for(i=0;i<5;i++) pass[i]=random(level);
-
- /* NEXT MAKE THE MD2 PASSWORD, FIRST GET CURRENT DATE TIME, THIS
- VALUE IS ALSO USED TO MAKE AN UNIQUE 10 CHARACTERS STRING.
- TO THOSE 10 CHAR WILL BE ADD THE USERS PASSWORD,
- THE RESULTING STRING WILL BE PASSED TO THE MD2 ALGHORITM */
- timet=time(NULL);
- sprintf(buffer,"%010.10ld%s",timet,Password);
- MD2Init(&context);
- MD2Update(&context,(unsigned char *)buffer,level+10);
- MD2Final(MD2digest,&context);
-
- /* NOW CONVERT 16 MD2 CHARACTERS TO LITERAL 32 BYTE HEX NOTATION */
- for(i=0;i<16;i++) sprintf(&tmp[i*2],"%02x",MD2digest[i]);
-
- /* OPEN THE USER FILENAME, IF THE FILE DO NOT EXIST, WILL BE CREATED
- OTHERWISE WILL BE OPENED FOR READ AND WRITE */
- if((pf=fopen(UserFile,access(UserFile,0)?"wt":"rt+"))==NULL) error();
-
- /* NOTE THAT THE FIRST LINE OF THE FILE HAVE ALWAYS THE SAME SIZE, THIS
- LINE IS USED TO STORE THE CALCULATED ANSWER, FIRST THE 5 LETTER MODE
- A SPACE, AND NEXT THE 32 BYTE MD2 */
- rewind(pf);
- fprintf(pf,"%c%c%c%c%c %s\n",Password[pass[0]],Password[pass[1]],
- Password[pass[2]],Password[pass[3]],Password[pass[4]],tmp);
-
- /* NOW GO TO THE END OF FILE, AND STORE THE DATE TIME FOR THIS LOGON */
- fseek(pf,0L,SEEK_END);
- fprintf(pf,"%s",ctime(&timet));
- if(ferror(pf)) error();
- fclose(pf);
-
- /* AT THE END, SEND TO THE USER THE PROMPT, THE 5 NUMBERS, AND MD2
- REQUEST PASSWORD */
- printf("\n%s %d %d %d %d %d [%010.10ld]\n",
- BbsPrompt,pass[0]+1,pass[1]+1,pass[2]+1,pass[3]+1,pass[4]+1,timet);
- return 1; /* CON_FILT MUST BE CALLED AGAIN */
- }
-
-
- /* LEVEL 1, CON_FILT RECEIVE THE PASSWORD ANSWER FROM THE USER */
-
- /* FIRST OPEN THE USER FILE AND RETRIEVE THE 5 LETTER AND MD2 CORRECTED DATA */
- if((pf=fopen(UserFile,"rt"))==NULL) error();
- if(!fgets(buffer,80,pf)) error();
- if(sscanf(buffer," %5s %32s",BbsPrompt,tmp)!=2) error();
- i=0;
-
- /* IF USER ANSWER IS EXACTLY 32 BYTE LONG, TREAT THE DATA LIKE MD2, OTHERWISE
- LIKE A 5 LETTERS PASSWORD */
- if(strlen(av[7])==32) i=stricmp(av[7],tmp); /* yes, use md2 password, ignoring case */
- else i=strcmp(av[7],BbsPrompt);
-
- /* IF INCORRECT PASSWORD, DISCONNECT THE USER, CLOSE BUT NOT DELETE THE
- USERS FILE */
- if(i) {
- puts("\n*** Password error.\n");
- fclose(pf);
- return 2;
- }
-
- /* RIGHT PASSWORD, BEFORE DELETE THE USER FILE, SEND TO THE USER ALL
- UNSUCCESFUL LOGON REGISTERED IN THE FILE (IF EXIST) */
-
- /* REMEMBER THAT THE LAST LINE IN THE FILE IS >THIS CONNECTION TIME<
- AND MUST NOT BE SEND, SINCE THIS CONNETCTION WAS SUCCESFUL */
- fgets(tmp,80,pf);
- while(fgets(buffer,80,pf))
- {
- if(level)
- {
- level=0;
- puts("\n*** WARNING -> Attempt to connect and password failure on:");
- }
- printf(tmp);
- strcpy(tmp,buffer);
- }
- puts("");
- fclose(pf);
- unlink(UserFile);
- return 0;
- }
-
- void error(void)
- {
- puts("\n*** Connection filtering: System error.\n");
- exit(2);
- }
-